package com.hengxinguotong.zhihuichengjian.fragment;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdate;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.CameraPosition;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MyLocationStyle;
import com.google.gson.Gson;
import com.hengxinguotong.zhihuichengjian.R;
import com.hengxinguotong.zhihuichengjian.bean.MapBuildingBean;
import com.hengxinguotong.zhihuichengjian.bean.MapBuildingRst;
import com.hengxinguotong.zhihuichengjian.ui.MainActivity;
import com.hengxinguotong.zhihuichengjian.ui.app.BaseFragment;
import com.hengxinguotong.zhihuichengjian.utils.SPUtil;
import com.hengxinguotong.zhihuichengjian.utils.UIHelper;
import com.hengxinguotong.zhihuichengjian.utils.Utils;
import com.hengxinguotong.zhihuichengjian.utils.map.ClusterClickListener;
import com.hengxinguotong.zhihuichengjian.utils.map.ClusterItem;
import com.hengxinguotong.zhihuichengjian.utils.map.ClusterOverlay;
import com.hengxinguotong.zhihuichengjian.utils.map.ClusterRender;
import com.hengxinguotong.zhihuichengjian.utils.map.RegionItem;
import com.hengxinguotong.zhihuichengjian.widget.CustomOperativeDialog;
import com.lidroid.xutils.http.RequestParams;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;

/**
 * 项目地图
 * Created by CS-Yong
 * 2019/9/23  15:31
 */
public class MapFragment extends BaseFragment
        implements AMap.OnMapLoadedListener, AMap.OnMapClickListener, ClusterRender, ClusterClickListener, AMapLocationListener, LocationSource {
    private final String TAG = getClass().getSimpleName();

    public static final LatLng WUHAN = new LatLng(30.57881467,114.30175781);// 武汉市经纬度

    @BindView(R.id.map)
    MapView mMapView;
    private View rootView = null;
    private MainActivity mainActivity;
    private Unbinder mUnbinder;
    private AMap aMap;
    private UiSettings uiSettings;
    private ClusterOverlay mClusterOverlay;
    private LocationSource.OnLocationChangedListener mListener;
    //声明AMapLocationClient类对象
    public AMapLocationClient mLocationClient;
    //声明AMapLocationClientOption对象
    private AMapLocationClientOption mLocationOption;

    private Map<Integer, Drawable> mBackDrawAbles = new HashMap<Integer, Drawable>();

    private int clusterRadius = 50;
    private LatLng myLatLng;
    private LatLng mCurrentLatLng;  //当前点击项目坐标
    private List<MapBuildingBean> mProjectList = new ArrayList<>();

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(android.os.Message msg) {
        }
    };

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if (rootView == null) {
            rootView = inflater.inflate(R.layout.fragment_map, null);
        }
        mainActivity = (MainActivity) getActivity();
        mUnbinder = ButterKnife.bind(this, rootView);
        initWidget(rootView,savedInstanceState);
        return rootView;
    }


    @Override
    public void onLazyLoad() {
        initData();
    }


    protected void initWidget(View root, Bundle savedInstanceState) {
        mMapView.onCreate(savedInstanceState);
        if (aMap == null) {
            aMap = mMapView.getMap();
            uiSettings = aMap.getUiSettings();
            aMap.setOnMapLoadedListener(this);
            aMap.setOnMapClickListener(this);
            changeCamera(
                    CameraUpdateFactory.newCameraPosition(new CameraPosition(
                            WUHAN, 12, 0, 0)));
        }
        uiSettings.setZoomControlsEnabled(false); //隐藏缩放控件

        // 聚合功能的覆盖物
        mClusterOverlay = new ClusterOverlay(aMap,
                (int) UIHelper.dp2px(mainActivity, clusterRadius),
                this.getActivity());
        mClusterOverlay.setClusterRenderer(this);
        mClusterOverlay.setOnClusterClickListener(this);
        //定位
        initLocation();
    }

    private void initData(){
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                getMapConstruction();
            }
        }, 500);
    }

    @OnClick(R.id.bt_test)
    public void onClickTest(){
        initData();
    }

    /**
     * 初始化定位
     */
    private void initLocation() {
        // 自定义系统定位小蓝点--我的位置
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory
                .fromResource(R.mipmap.ic_my_loc));// 设置小蓝点的图标
        myLocationStyle.strokeColor(getResources().getColor(R.color.blue_50));// 设置圆形的边框颜色
        myLocationStyle.radiusFillColor(Color.argb(100, 29, 161, 242));// 设置圆形的填充颜色
        myLocationStyle.strokeWidth(1.0f);// 设置圆形的边框粗细
        aMap.setMyLocationStyle(myLocationStyle);
        aMap.setLocationSource(this);// 设置定位资源。如果不设置此定位资源则定位按钮不可点击。并且实现activate激活定位,停止定位的回调方法
        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(false);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
    }


    /**
     * 根据动画按钮状态，调用函数animateCamera或moveCamera来改变可视区域
     */
    private void changeCamera(CameraUpdate update) {
        aMap.moveCamera(update);
    }
    /**
     * 网络获取地图数据
     */
    private void getMapConstruction() {
        String userId = SPUtil.getString(baseActivity,"userId");

        RequestParams params = new RequestParams();
        params.addBodyParameter("uuid",userId);
        params.addBodyParameter("status","1");
//        params.setContentType("application/x-www-form-urlencoded");

        Utils.requestData(getResources().getString(R.string.loading),mainActivity, "/construction/getConstructionDataByUserId/" + SPUtil.getString(mainActivity, "uuid"),
                params, new Utils.ListenerJson() {
                    @Override
                    public void onSuccess(String json) {
                        Gson gson = new Gson();
                        MapBuildingRst mapBuildingRst = gson.fromJson(json, MapBuildingRst.class);
                        if(mapBuildingRst.getStatus() == 1){
                            List<MapBuildingBean> beanList = mapBuildingRst.getValue();
                            if (beanList != null && beanList.size()>0) {
                                mProjectList.clear();
                                mProjectList.addAll(beanList);

                                updateMapInfo2MapView(mProjectList);
                            }

                        }else{
                            mainActivity.showToast(mapBuildingRst.getMsg());
                        }
                    }

                    @Override
                    public void onFailure(String json) {
                        try {
                            JSONObject object = new JSONObject(json);
                            String msg = object.getString("msg");
                            mainActivity.showToast(msg);
                        } catch (JSONException e) {
                            e.printStackTrace();
                            mainActivity.showToast("系统异常");
                        }
                    }
                });
    }


    //异步的将数据同步到地图上
    private void updateMapInfo2MapView(final List<MapBuildingBean> projectList) {
        new Thread() {
            public void run() {
                List<ClusterItem> items = new ArrayList<ClusterItem>();
                for (MapBuildingBean p : projectList) {
                    String latitude = p.getLat();
                    String longitude = p.getLng();

                    double x = Double.parseDouble(latitude);
                    double y = Double.parseDouble(longitude);
                    LatLng latLng = new LatLng(x, y, false);
                    RegionItem regionItem = new RegionItem<MapBuildingBean>(latLng, p.getName(), p);
                    items.add(regionItem);
                }
                for (int i = 0; i < items.size(); i++) {
                    mClusterOverlay.addClusterItem(items.get(i));
                }
            }
        }.start();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mUnbinder.unbind();
    }

    //定位成功的监听
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation != null) {

            if (mListener != null) {
                mListener.onLocationChanged(aMapLocation);// 显示系统小蓝点-我的位置
            }

            if (aMapLocation.getErrorCode() == 0) {
                myLatLng = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myLatLng, 14));
                String city = aMapLocation.getCity();
                String address = aMapLocation.getAddress();
                //                addMarkerToMap(latLng,city,address);
            } else {
                //定位失败时，可通过ErrCode（错误码）信息来确定失败的原因，errInfo是错误信息，详见错误码表。
                Log.e("AmapError", "location Error, ErrCode:" + aMapLocation.getErrorCode() + ", errInfo:"
                        + aMapLocation.getErrorInfo());
            }
        }
    }

    @Override
    public void onMapClick(LatLng latLng) {

    }

    @Override
    public void onMapLoaded() {

    }

    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        mListener = onLocationChangedListener;
        if (mLocationClient == null) {
            mLocationClient = new AMapLocationClient(getActivity());
            mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mLocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            mLocationOption.setOnceLocation(true);
            //设置是否返回地址信息（默认返回地址信息）
            mLocationOption.setNeedAddress(true);
            //设置定位参数
            mLocationClient.setLocationOption(mLocationOption);
            mLocationClient.startLocation();
        }
    }

    @Override
    public void deactivate() {
        mListener = null;
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
        }
        mLocationClient = null;
    }

    @Override
    public void onClick(Marker marker, List<ClusterItem> clusterItems) {
        LatLngBounds.Builder builder = new LatLngBounds.Builder();
        for (ClusterItem clusterItem : clusterItems) {
            builder.include(clusterItem.getPosition());
        }
        LatLngBounds latLngBounds = builder.build();
        aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 0));

        if (!marker.getPosition().equals(myLatLng) && clusterItems.size() == 1) {
            //点击的marker不是自己位置的那个marker
            //显示当前dialog
            mCurrentLatLng = marker.getPosition();
            showOprativeDialog(((RegionItem) clusterItems.get(0)).getData());
        }
    }


    /**
     * 展示地图dialog
     */
    private void showOprativeDialog(MapBuildingBean card) {
        CustomOperativeDialog dialog = new CustomOperativeDialog<MapBuildingBean>(mainActivity);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setLatLng(mCurrentLatLng);
        dialog.setData(card);
        dialog.showOprativeDialog();
    }

    private Bitmap drawCircle(int radius, int color) {
        Bitmap bitmap = Bitmap.createBitmap(radius * 2, radius * 2,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        RectF rectF = new RectF(0, 0, radius * 2, radius * 2);
        paint.setColor(color);
        canvas.drawArc(rectF, 0, 360, true, paint);
        return bitmap;
    }

    @Override
    public Drawable getDrawAble(int clusterNum) {
        int radius = UIHelper.dp2px(mainActivity, 40);
        if (clusterNum == 1) {
            Drawable bitmapDrawable = mBackDrawAbles.get(1);
            if (bitmapDrawable == null) {
                bitmapDrawable =
                        getResources().getDrawable(
                                R.mipmap.ic_map_building);
            }
            return bitmapDrawable;
        } else if (clusterNum < 5) {

            Drawable bitmapDrawable = mBackDrawAbles.get(2);
            if (bitmapDrawable == null) {
                bitmapDrawable = new BitmapDrawable(null, drawCircle(radius,
                        Color.argb(100, 252, 124, 120)));
                mBackDrawAbles.put(2, bitmapDrawable);
            }

            return bitmapDrawable;
        } else if (clusterNum < 10) {
            Drawable bitmapDrawable = mBackDrawAbles.get(3);
            if (bitmapDrawable == null) {
                bitmapDrawable = new BitmapDrawable(null, drawCircle(radius,
                        Color.argb(150, 252, 124, 120)));
                mBackDrawAbles.put(3, bitmapDrawable);
            }

            return bitmapDrawable;
        } else {
            Drawable bitmapDrawable = mBackDrawAbles.get(4);
            if (bitmapDrawable == null) {
                bitmapDrawable = new BitmapDrawable(null, drawCircle(radius,
                        Color.argb(250, 252, 124, 120)));
                mBackDrawAbles.put(4, bitmapDrawable);
            }

            return bitmapDrawable;
        }
    }
}
